home *** CD-ROM | disk | FTP | other *** search
/ Revista do CD-ROM 97 / CD-ROM 97 / CD-ROM 97.iso / internet / ghostzilla / ghsetup.exe / chrome / comm.jar / content / editor / EdReplace.js < prev    next >
Encoding:
JavaScript  |  2002-04-09  |  10.6 KB  |  322 lines

  1. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  *
  13.  * The Original Code is Mozilla Communicator client code, released March
  14.  * 31, 1998.
  15.  *
  16.  * The Initial Developer of the Original Code is Netscape Communications
  17.  * Corporation. Portions created by Netscape are
  18.  * Copyright (C) 1998 Netscape Communications Corporation. All
  19.  * Rights Reserved.
  20.  *
  21.  * Contributor(s): Kin Blas <kin@netscape.com>
  22.  * Contributor(s): Akkana Peck <akkana@netscape.com>
  23.  *
  24.  */
  25.  
  26. var gReplaceDialog;      // Quick access to document/form elements.
  27. var gFindInst;           // nsIWebBrowserFind that we're going to use
  28. var gFindService;        // Global service which remembers find params
  29. var gEditor;             // the editor we're using
  30.  
  31. function initDialogObject()
  32. {
  33.   // Create gReplaceDialog object and initialize.
  34.   gReplaceDialog = new Object();
  35.   gReplaceDialog.findInput       = document.getElementById("dialog.findInput");
  36.   gReplaceDialog.replaceInput    = document.getElementById("dialog.replaceInput");
  37.   gReplaceDialog.caseSensitive   = document.getElementById("dialog.caseSensitive");
  38.   gReplaceDialog.wrap            = document.getElementById("dialog.wrap");
  39.   gReplaceDialog.searchBackwards = document.getElementById("dialog.searchBackwards");
  40.   gReplaceDialog.findNext        = document.getElementById("findNext");
  41.   gReplaceDialog.replace         = document.getElementById("replace");
  42.   gReplaceDialog.replaceAndFind  = document.getElementById("replaceAndFind");
  43.   gReplaceDialog.replaceAll      = document.getElementById("replaceAll");
  44.   gEditor                        = null;
  45. }
  46.  
  47. function loadDialog()
  48. {
  49.   // Set initial dialog field contents.
  50.   // Set initial dialog field contents. Use the gFindInst attributes first,
  51.   // this is necessary for window.find()
  52.   gReplaceDialog.findInput.value         = (gFindInst.searchString
  53.                                             ? gFindInst.searchString
  54.                                             : gFindService.searchString);
  55.   gReplaceDialog.replaceInput.value = gFindService.replaceString;
  56.   gReplaceDialog.caseSensitive.checked   = (gFindInst.matchCase
  57.                                             ? gFindInst.matchCase
  58.                                             : gFindService.matchCase);
  59.   gReplaceDialog.wrap.checked            = (gFindInst.wrapFind
  60.                                             ? gFindInst.wrapFind
  61.                                             : gFindService.wrapFind);
  62.   gReplaceDialog.searchBackwards.checked = (gFindInst.findBackwards
  63.                                             ? gFindInst.findBackwards
  64.                                             : gFindService.findBackwards);
  65.  
  66.   doEnabling();
  67. }
  68.  
  69. function onLoad()
  70. {
  71.   // Get the xul <editor> element:
  72.   var editorXUL = window.opener.document.getElementById("content-frame");
  73.  
  74.   // Get the nsIWebBrowserFind service:
  75.   gFindInst = editorXUL.webBrowserFind;
  76.  
  77.   try {
  78.   // get the find service, which stores global find state
  79.     gFindService = Components.classes["@mozilla.org/find/find_service;1"]
  80.                          .getService(Components.interfaces.nsIFindService);
  81.   } catch(e) { dump("No find service!\n"); gFindService = 0; }
  82.  
  83.   // Init gReplaceDialog.
  84.   initDialogObject();
  85.  
  86.   try {
  87.     gEditor = editorXUL.editorShell.editor.QueryInterface(Components.interfaces.nsIPlaintextEditor);
  88.   } catch(e) { dump("Couldn't get an editor! " + e + "\n"); }
  89.   // If we don't get the editor, then we won't allow replacing.
  90.  
  91.   // Change "OK" to "Find".
  92.   //dialog.find.label = document.getElementById("fBLT").getAttribute("label");
  93.  
  94.   // Fill dialog.
  95.   loadDialog();
  96.  
  97.   if (gReplaceDialog.findInput.value)
  98.     gReplaceDialog.findInput.select();
  99.   else
  100.     gReplaceDialog.findInput.focus();
  101. }
  102.  
  103. function onUnload() {
  104.   // Disconnect context from this dialog.
  105.   gFindReplaceData.replaceDialog = null;
  106. }
  107.  
  108. function saveFindData()
  109. {
  110.   // Set data attributes per user input.
  111.   if (gFindService)
  112.   {
  113.     gFindService.searchString  = gReplaceDialog.findInput.value;
  114.     gFindService.matchCase     = gReplaceDialog.caseSensitive.checked;
  115.     gFindService.wrapFind      = gReplaceDialog.wrap.checked;
  116.     gFindService.findBackwards = gReplaceDialog.searchBackwards.checked;
  117.   }
  118. }
  119.  
  120. function setUpFindInst()
  121. {
  122.   gFindInst.searchString  = gReplaceDialog.findInput.value;
  123.   gFindInst.matchCase     = gReplaceDialog.caseSensitive.checked;
  124.   gFindInst.wrapFind      = gReplaceDialog.wrap.checked;
  125.   gFindInst.findBackwards = gReplaceDialog.searchBackwards.checked;
  126. }
  127.  
  128. function onFindNext()
  129. {
  130.   // Transfer dialog contents to the find service.
  131.   saveFindData();
  132.   // set up the find instance
  133.   setUpFindInst();
  134.  
  135.   // Search.
  136.   var result = gFindInst.findNext();
  137.  
  138.   if (!result)
  139.   {
  140.     var bundle = document.getElementById("findBundle");
  141.     window.alert(bundle.getString("notFoundWarning"));
  142.     SetTextboxFocus(gReplaceDialog.findKey);
  143.     gReplaceDialog.findInput.select();
  144.     gReplaceDialog.findInput.focus();
  145.     return false;
  146.   } 
  147.   return true;
  148. }
  149.  
  150. function onReplace()
  151. {
  152.   if (!gEditor)
  153.     return;
  154.  
  155.   // Does the current selection match the find string?
  156.   var selection = gEditor.selection;
  157.  
  158.   var selStr = selection.toString();
  159.   var specStr = gReplaceDialog.findInput.value;
  160.   if (!gReplaceDialog.caseSensitive.checked)
  161.   {
  162.     selStr = selStr.toLowerCase();
  163.     specStr = specStr.toLowerCase();
  164.   }
  165.   // Unfortunately, because of whitespace we can't just check
  166.   // whether (selStr == specStr), but have to loop ourselves.
  167.   // N chars of whitespace in specStr can match any M >= N in selStr.
  168.   var matches = true;
  169.   var specLen = specStr.length;
  170.   var selLen = selStr.length;
  171.   if (selLen < specLen)
  172.     matches = false;
  173.   else
  174.   {
  175.     specArray = specStr.match(/\S+|\s+/g);
  176.     selArray = selStr.match(/\S+|\s+/g);
  177.     if ( specArray.length != selArray.length)
  178.       matches = false;
  179.     else
  180.     {
  181.       for (i=0; i<selArray.length; i++)
  182.       {
  183.         if (selArray[i] != specArray[i])
  184.         {
  185.           if ( selArray[i][0].search(/\s/) == -1 ||
  186.                specArray[i][0].search(/\s/) == -1)
  187.           {
  188.             // lowercase \s, not a space chunk -- match fails
  189.             matches = false;
  190.             break;
  191.           }
  192.           else if ( selArray[i].length < specArray[i].length )
  193.           {
  194.             // if it's a space chunk then we only care that sel be
  195.             // at least as long as spec
  196.             matches = false;
  197.             break;
  198.           }
  199.         }
  200.       }
  201.     }
  202.   }
  203.  
  204.   // If the current selection doesn't match the pattern,
  205.   // then we want to find the next match, but not do the replace.
  206.   // That's what most other apps seem to do.
  207.   if (!matches)
  208.     return onFindNext();
  209.  
  210.   // Transfer dialog contents to the find service.
  211.   saveFindData();
  212.  
  213.   gEditor.insertText(gReplaceDialog.replaceInput.value);
  214.   return true;
  215. }
  216.  
  217. function onReplaceAll()
  218. {
  219.   if (!gEditor)
  220.     return;
  221.  
  222.   var findStr = gReplaceDialog.findInput.value;
  223.   var repStr = gReplaceDialog.replaceInput.value;
  224.  
  225.   // Transfer dialog contents to the find service.
  226.   saveFindData();
  227.  
  228.   var finder = Components.classes["@mozilla.org/embedcomp/rangefind;1"].createInstance().QueryInterface(Components.interfaces.nsIFind);
  229.  
  230.   finder.caseSensitive = gReplaceDialog.caseSensitive.checked;
  231.   finder.findBackwards = gReplaceDialog.searchBackwards.checked;
  232.  
  233.   // Make a range containing the current selection, 
  234.   // so we don't go past it when we wrap.
  235.   var selection = gEditor.selection;
  236.   var selecRange;
  237.   if (selection.rangeCount > 0)
  238.     selecRange = selection.getRangeAt(0);
  239.   var origRange = selecRange.cloneRange();
  240.  
  241.   // We'll need a range for the whole document:
  242.   var wholeDocRange = gEditor.document.createRange();
  243.   var rootNode = gEditor.rootElement.QueryInterface(Components.interfaces.nsIDOMNode);
  244.   wholeDocRange.selectNodeContents(rootNode);
  245.  
  246.   // And start and end points:
  247.   var endPt = gEditor.document.createRange();
  248.  
  249.   if (gReplaceDialog.searchBackwards.checked)
  250.   {
  251.     endPt.setStart(wholeDocRange.startContainer, wholeDocRange.startOffset);
  252.     endPt.setEnd(wholeDocRange.startContainer, wholeDocRange.startOffset);
  253.   }
  254.   else
  255.   {
  256.     endPt.setStart(wholeDocRange.endContainer, wholeDocRange.endOffset);
  257.     endPt.setEnd(wholeDocRange.endContainer, wholeDocRange.endOffset);
  258.   }
  259.  
  260.   // Find and replace from here to end of document:
  261.   var foundRange;
  262.   while ((foundRange = finder.Find(findStr, wholeDocRange,
  263.                                    selecRange, endPt)) != null)
  264.   {
  265.     gEditor.selection.removeAllRanges();
  266.     gEditor.selection.addRange(foundRange);
  267.     gEditor.insertText(repStr);
  268.     selection = gEditor.selection;
  269.     if (selection.rangeCount <= 0) {
  270.       return;
  271.     }
  272.     selecRange = selection.getRangeAt(0);
  273.   }
  274.  
  275.   // If no wrapping, then we're done
  276.   if (!gReplaceDialog.wrap.checked)
  277.     return;
  278.  
  279.   // If wrapping, find from start/end of document back to start point.
  280.   if (gReplaceDialog.searchBackwards.checked)
  281.   {
  282.     // Collapse origRange to end
  283.     origRange.setStart(origRange.endContainer, origRange.endOffset);
  284.     // Set current position to document end
  285.     selecRange.setEnd(wholeDocRange.endContainer, wholeDocRange.endOffset);
  286.     selecRange.setStart(wholeDocRange.endContainer, wholeDocRange.endOffset);
  287.   }
  288.   else
  289.   {
  290.     // Collapse origRange to start
  291.     origRange.setEnd(origRange.startContainer, origRange.startOffset);
  292.     // Set current position to document start
  293.     selecRange.setStart(wholeDocRange.startContainer,
  294.                         wholeDocRange.startOffset);
  295.     selecRange.setEnd(wholeDocRange.startContainer, wholeDocRange.startOffset);
  296.   }
  297.  
  298.   while ((foundRange = finder.Find(findStr, wholeDocRange,
  299.                                    selecRange, origRange)) != null)
  300.   {
  301.     gEditor.selection.removeAllRanges();
  302.     gEditor.selection.addRange(foundRange);
  303.     gEditor.insertText(repStr);
  304.     selection = gEditor.selection;
  305.     if (selection.rangeCount <= 0) {
  306.       return;
  307.     }
  308.     selecRange = selection.getRangeAt(0);
  309.   }
  310. }
  311.  
  312. function doEnabling()
  313. {
  314.   var findStr = gReplaceDialog.findInput.value;
  315.   var repStr = gReplaceDialog.replaceInput.value;
  316.   gReplaceDialog.enabled = findStr;
  317.   gReplaceDialog.findNext.disabled = !findStr;
  318.   gReplaceDialog.replace.disabled = (!findStr || !repStr);
  319.   gReplaceDialog.replaceAndFind.disabled = (!findStr || !repStr);
  320.   gReplaceDialog.replaceAll.disabled = (!findStr || !repStr);
  321. }
  322.